// 视频采集控制器模块
module controller.CollectController;

import std.typecons : Tuple;
import core.thread : Thread;
import core.time : msecs;

import archttp.HttpRequest : HttpRequest;
import archttp.HttpResponse : HttpResponse;
import archttp.HttpStatusCode : HttpStatusCode;

import model.Teleplay;
import model.TeleplayVlink;
import model.Movie;
import model.MovieVlink;
import model.Animation;
import model.AnimationVlink;
import repository.TeleplayRepo;
import repository.TeleplayLinksRepo;
import repository.MovieRepo;
import repository.MovieLinksRepo;
import repository.AnimationRepo;
import repository.AnimationLinksRepo;

import utils.VideoCollect;
import utils.RespData;
import utils.ObjMapping : ObjMapping;
import utils.SecurityVerification : signValidator;

// import std.stdio;

// 视频信息采集控制器
class CollectController
{
    TeleplayRepo _tRepo; // 电视剧仓储
    TeleplayLinksRepo _tlRepo; // 电视剧视频链接仓储
    MovieRepo _mRepo; // 电影仓储
    MovieLinksRepo _mlRepo; // 电影视频链接仓储
    AnimationRepo _aRepo; // 动漫仓储
    AnimationLinksRepo _alRepo; // 动漫视频链接仓储
    this ()
    {
        _tRepo = new TeleplayRepo();
        _tlRepo = new TeleplayLinksRepo();
        _mRepo = new MovieRepo();
        _mlRepo = new MovieLinksRepo();
        _aRepo = new AnimationRepo();
        _alRepo = new AnimationLinksRepo();
    }

    // 接收前端提交数据的结构体
    struct PostData
    {
        string cate;
        string[] urls;
        string sign;
    }

    /** 
     * 视频信息采集action
     */
    public void collect (HttpRequest req, HttpResponse resp)
    {
        import mir.deser.json : deserializeJson;

        // 接收前端数据,反序列化
        // JSONValue json = parseJSON(req.body());
        // PostData postData = json.fromJSON!(PostData);
        // string cate = postData.cate;
        // string[] urls = postData.urls;

        PostData postData = req.body().deserializeJson!PostData;
        string cate = postData.cate;
        string[] urls = postData.urls;
        string sign = postData.sign;

        // 判空
        if (sign == "" || cate == "" || urls.length == 0)
        {
            resp.code(HttpStatusCode.BAD_REQUEST).json(RespData.newData(400, "错误的请求")).send();
            return;
        }

        import std.format : format;

        string reqParamsStr = format("%s%s", cate, urls.length);
        if (!signValidator(reqParamsStr, sign))
        {
            resp.code(HttpStatusCode.FORBIDDEN).json(RespData.newData(403, "签名不正确！")).send();
            return;
        }

        // 网络视频信息采集工作
        switch (cate)
        {
        case "电视剧":
            foreach (url; urls)
            {
                Tuple!(TeleplayDtoFromCreate, TeleplayVlinkDtoFromCreate[]) teleplay = VideoCollect.getTeleplayInfo(
                    url);
                TeleplayDtoFromCreate teleplayInfo = teleplay[0];
                TeleplayVlinkDtoFromCreate[] teleplayLinks = teleplay[1];
                if (teleplayInfo is null || teleplayLinks is null)
                {
                    continue;
                }
                bool res1 = _tRepo.addTeleplay(ObjMapping.mappingToObject!(Teleplay, TeleplayDtoFromCreate)(
                        teleplayInfo));
                if (!res1)
                {
                    continue;
                }
                // // 转换为实体对象
                // TeleplayVlink[] tls = [];
                // foreach (tl; teleplayLinks)
                // {
                //     tls ~= ObjMapping.mappingToObject!(TeleplayVlink, TeleplayVlinkDtoFromCreate)(tl);
                // }
                // // 批量添加电视剧视频链接
                // _tlRepo.addTeleplayLinkBatch(tls);

                // 逐一添加
                foreach (tvdfc; teleplayLinks)
                {
                    TeleplayVlink tv = ObjMapping.mappingToObject!(TeleplayVlink, TeleplayVlinkDtoFromCreate)(
                        tvdfc);
                    // 逐一添加
                    bool res = _tlRepo.addTeleplayLink2(tv);
                    if (!res) // 失败，退出
                    {
                        return;
                    }
                }

                Thread.sleep(300.msecs);
            }
            break;
        case "电影":
            foreach (url; urls)
            {
                Tuple!(MovieDtoFromCreate, MovieVlinkDtoFromCreate[]) movie = VideoCollect.getMovieInfo(
                    url);
                MovieDtoFromCreate movieInfo = movie[0];
                MovieVlinkDtoFromCreate[] movieLinks = movie[1];
                if (movieInfo is null || movieLinks is null)
                {
                    continue;
                }
                bool res1 = _mRepo.addMovie(ObjMapping.mappingToObject!(Movie, MovieDtoFromCreate)(
                        movieInfo));
                if (!res1)
                {
                    continue;
                }

                // 转换为实体对象
                MovieVlink[] mls = [];
                foreach (ml; movieLinks)
                {
                    mls ~= ObjMapping.mappingToObject!(MovieVlink, MovieVlinkDtoFromCreate)(ml);
                }
                // 批量添加电影视频链接
                _mlRepo.addMovieLinkBatch(mls);

                Thread.sleep(220.msecs);
            }
            break;
        case "动漫":
            foreach (url; urls)
            {
                Tuple!(AnimationDtoFromCreate, AnimationVlinkDtoFromCreate[]) animation = VideoCollect.getAnimationInfo(
                    url);
                AnimationDtoFromCreate animationInfo = animation[0];
                AnimationVlinkDtoFromCreate[] animationLinks = animation[1];
                if (animationInfo is null || animationLinks is null)
                {
                    continue;
                }
                bool res1 = _aRepo.addAnimation(ObjMapping.mappingToObject!(Animation, AnimationDtoFromCreate)(
                        animationInfo));
                if (!res1)
                {
                    continue;
                }
                // // 转换为实体对象
                // AnimationVlink[] aLinks = [];
                // foreach (al; animationLinks)
                // {
                //     aLinks ~= ObjMapping.mappingToObject!(AnimationVlink, AnimationVlinkDtoFromCreate)(al);
                // }

                // // 批量添加动漫视频链接
                // _alRepo.addAnimationLinkBatch(aLinks);

                // 逐一添加
                foreach (avdfc; animationLinks)
                {
                    // 转换为实体对象
                    AnimationVlink av = ObjMapping.mappingToObject!(AnimationVlink, AnimationVlinkDtoFromCreate)(
                        avdfc);
                    // 逐一添加
                    bool res = _alRepo.addAnimationLink2(av);
                    if (!res) // 失败，退出
                    {
                        return;
                    }
                }

                Thread.sleep(220.msecs);
            }
            break;
        default:
            resp.code(HttpStatusCode.BAD_REQUEST).json(RespData.newData(400, "错误的请求")).send();
            return;
        }

        resp.json(RespData.newData(200, "完成")).send();
    }

}
